/**
 *******************************************************************************
 * @brief		CooCox OS demo test file
 * @file		main.c
 * @version		V1.00	Initial version
 * @version		V1.10	The first version
 * @date		2010.09.3
 *
 * @details		This file is part of CooCox RTOS demo test.
 *******************************************************************************
 * @copy
 *
 * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
 *******************************************************************************
 */

/*---------------------------------- Inlcude ---------------------------------*/
#include <stdio.h>
#include <CoOS.h>			 			/*!< CooCox RTOS header file.		  */

#include "ir_remo_ctrl.h"

#include "NUC1xx.h"
#include "AppConfig.h"
#include "Driver\DrvADC.h"
//#include "Driver\DrvUART.h"
#include "Driver\DrvGPIO.h"
#include "Driver\DrvRTC.h"


#include "usb_vcom.h"
#include "temperature.h"


/*---------------------------------- Define  ---------------------------------*/

#define	TIME_SET_PRI 		2		   	/*!< Priority of 'time_set' task.	  */
#define LCD_BLINK_PRI		3			/*!< Priority of 'tcd_blink' task.	  */
#define LCD_DISPLAY_PRI		4			/*!< Priority of 'display_adc' task.  */
#define UART_PRINT_PRI 		4		   	/*!< Priority of 'tart_print' task.	  */
#define LED_DISPLAY_PRI		5			/*!< Priority of 'led_display' task.  */
#define TIME_DISRPLAY_PRI 	5			/*!< Priority of 'time_display' task. */

// Task defines:
//	1. Initial task:	Initialize hardwares and pheis
OS_STK   task_init_Stk[TASK_STK_SIZE];	 	/*!< Stack of 'task_init' task.	  */

//	2. USB listen task:
//		Waiting for USB connect, then start shell task
//#define		USB_LISTEN_PRI		5
//OS_STK   	task_usb_listen_Stk[TASK_STK_SIZE];	 	/*!< Stack of 'task_init' task.	  */



//	4.  A task for test




/*---------------------------------- Variable Define -------------------------*/
OS_STK   lcd_display_adc_Stk[TASK_STK_SIZE];/*!< Stack of 'lcd_display_adc' . */
OS_STK   uart_print_Stk[TASK_STK_SIZE];		/*!< Stack of 'uart_print' task.  */
OS_STK   led_display_Stk[TASK_STK_SIZE];	/*!< Stack of 'led_display' task. */
OS_STK   time_display_Stk[TASK_STK_SIZE];	/*!< Stack of 'time_display' task.*/
OS_STK   time_set_Stk[TASK_STK_SIZE];		/*!< Stack of 'time_set' task. 	  */
OS_STK   lcd_blink_Stk[TASK_STK_SIZE];	   	/*!< Stack of 'lcd_blink' task.   */

// Mutexes


OS_MutexID	mut_uart,mut_lcd;	  /*!< Save id of mutex.			 		  */
OS_FlagID	button_sel_flg;		  /*!< Flag id,related to 'EVT_BUTTON_SEL'.	  */
OS_FlagID	button_add_flg;		  /*!< Flag id,related to 'EEVT_BUTTON_ADD'.  */
OS_FlagID	lcd_blink_flg;		  /*!< Flag id,related to 'lcd_blink' task.	  */
OS_FlagID	time_display_flg; 	  /*!< Flag id,related to 'time_display' task.*/


U16 EVT_BUTTON_SEL   = 0x0001;	 	/*!< Flag related to Select button.	   	  */
U16 EVT_BUTTON_ADD   = 0x0002;		/*!< Flag related to add button.	      */
U16 EVT_BUTTON_BLINK = 0x0004;	 	/*!< Flag related to lcd_blink_flg.	      */
U16 EVT_BUTTON_DISPL = 0x0008;		/*!< Flag related to time_display_flg.	  */

OS_TID		    lcd_blink_id = 0; 		/*!< Save id of 'lcd_blink' task.	  */
OS_TID			time_display_id;		/*!< Save id of 'time_display' task.  */
OS_EventID		mbox0;			   		/*!< Save id of mailbox.			  */
unsigned char 	errinfo[30];	   		/*!< Error information.				  */

unsigned char timeflag = 0;

unsigned char time[3] = {00,00,12};		/*!< Format: { second,minute,hour }	  */


char chart[9] = {'0','0',':','0','0',':','0','0','\0'};		/*!< Time buffer  */



extern unsigned short int  ADC_ConvertedValue;/*!< The value which AD converted*/

/*---------------------------------- Function declare ------------------------*/
void lcd_blink   	(void *pdata);	  /*!< Lcd blink when setting time. 	  */
void lcd_display_adc(void *pdata);	  /*!< Display value of adc convert in LCD*/
void uart_print		(void *pdata);	  /*!< Print value of adc convert by UART.*/
void led_blink		(void *pdata);	  /*!< LED blinky.						  */
void time_display  	(void *pdata);	  /*!< Display real time.				  */
void time_set		(void *pdata);	  /*!< Setting time.					  */
void task_init    	(void *pdata);	  /*!< Initialization task.				  */






/**
 *******************************************************************************
 * @brief		Print task.
 * @param[in] 	pdata	A pointer to parameter passed to task.
 * @param[out] 	None
 * @retval		None
 *
 * @details	  	This task print adc value by UART.
 *******************************************************************************
 */
void uart_print(void *pdata)
{

}



/**
 *******************************************************************************
 * @brief		time_display task
 * @param[in] 	pdata	A pointer to parameter passed to task.
 * @param[out] 	None
 * @retval		None
 *
 * @details	    This task use to display time in LCD.
 *******************************************************************************
 */
void time_display(void *pdata)
{
//	static unsigned char tim[3] = {0,0,0};
//	static unsigned char *ptr;
//
//	pdata = pdata;
//	for (;;)
//	{
//		CoWaitForSingleFlag(time_display_flg,0);
//		ptr = (unsigned char *)CoPendMail(mbox0,0,&errinfo[30]);
//
//		CoEnterMutexSection(mut_lcd);
//		if (tim[0] != *(ptr+0))
//		{
//			tim[0]   = *(ptr+0);
//		   	chart[6] = tim[0]/10 + '0';
//			chart[7] = tim[0]%10 + '0';
//		}
//		if (tim[1] != *(ptr+1))
//		{
//			tim[1] 	 = *(ptr+1);
//		   	chart[3] = tim[1]/10 + '0';
//			chart[4] = tim[1]%10 + '0';
//		}
//		if (tim[2] != *(ptr+2))
//		{
//			tim[2] = *(ptr+2);
//		   	chart[0] = tim[2]/10 + '0';
//			chart[1] = tim[2]%10 + '0';
//		}
//
//		set_cursor(7, 0);
//		lcd_print (chart);
//
//		CoLeaveMutexSection(mut_lcd);
//	}
}

/**
 *******************************************************************************
 * @brief		Set time task
 * @param[in] 	pdata	A pointer to parameter passed to task.
 * @param[out] 	None
 * @retval		None
 *
 * @details	  	This task use to set time.
 *******************************************************************************
 */
void time_set(void *pdata)
{
//	static unsigned char bct = 0;			/* Button calc 					  */
//	U16 evtmp = 0;
//
//	pdata = pdata;
//	for (;;)
//	{
//		evtmp = CoWaitForMultipleFlags(EVT_BUTTON_SEL|EVT_BUTTON_ADD,OPT_WAIT_ANY,0,&errinfo[20]);
//		if(errinfo[20] != E_OK)
//			uart_printf("\r Flag ERROR:\n");
//
//		if (evtmp == EVT_BUTTON_SEL)
//		{
//		 	bct++;
//			switch (bct)
//			{
//				case 1:
//					timeflag = 1;
//					if(lcd_blink_id == 0)
//						lcd_blink_id = CoCreateTask (lcd_blink,(void *)0, LCD_BLINK_PRI ,&lcd_blink_Stk[TASK_STK_SIZE - 1], TASK_STK_SIZE );
//
//					DisableRTCInterrupt();
//
//					CoClearFlag(time_display_flg);
//					CoSetFlag(lcd_blink_flg);
//					break;
//				case 2:
//					timeflag = 2;
//					break;
//				case 3:
//					timeflag = 3;
//					break;
//				case 4:
//					bct = 0;
//
//				   	CoClearFlag(lcd_blink_flg);
//					CoSetFlag(time_display_flg);
//
//					EnableRTCInterrupt();
//					break;
//				default: break;
//			};
//			CoTickDelay(40);
//			CoClearFlag(button_sel_flg);
//		}
//		else if(evtmp == EVT_BUTTON_ADD)
//		{
//			CoEnterMutexSection(mut_lcd);
//		 	switch (bct)
//			{
//				case 1:
//					time[0]++;
//					if (time[0] >= 60)
//						time[0] = 0;
//					chart[6] = time[0]/10 + '0';
//					chart[7] = time[0]%10 + '0';
//					break;
//				case 2:
//					time[1]++;
//					if (time[1] >= 60)
//						time[1] = 0;
//					chart[3] = time[1]/10 + '0';
//					chart[4] = time[1]%10 + '0';
//					break;
//
//				case 3:
//					time[2]++;
//					if (time[2] >= 24)
//						time[2] = 0;
//					chart[0] = time[2]/10 + '0';
//					chart[1] = time[2]%10 + '0';
//					break;
//
//				default: break;
//			}
//			set_cursor(7, 0);
//			lcd_print (chart);
//
//			CoLeaveMutexSection(mut_lcd);
//			CoTickDelay(40);
//			CoClearFlag(button_add_flg);
//		}
//
//	}
}

/**
 *******************************************************************************
 * @brief		Initialization task
 * @param[in] 	pdata	A pointer to parameter passed to task.
 * @param[out] 	None
 * @retval		None
 *
 * @details	    This task is called to initial hardware and created tasks.
 *******************************************************************************
 */
void task_init(void *pdata)
{
	UNLOCKREG();

	// Config GPIO
	DrvGPIO_Open(E_GPB, 0,  E_IO_OUTPUT);	// LED on board
    DrvGPIO_SetBit(E_GPB, 0);				// turn off

	DrvGPIO_Open(E_GPB, 1, E_IO_OUTPUT);
	DrvGPIO_SetBit(E_GPB, 1);

	DrvGPIO_Open(E_GPB, 2, E_IO_OUTPUT);
	DrvGPIO_SetBit(E_GPB, 2);

	DrvGPIO_Open(E_GPB, 3, E_IO_OUTPUT);
	DrvGPIO_SetBit(E_GPB, 3);


	pdata = pdata;

    /* Initiate Time buffer for LCD display */
	chart[0] = time[2]/10 + '0';
	chart[1] = time[2]%10 + '0';

	chart[3] = time[1]/10 + '0';
	chart[4] = time[1]%10 + '0';

	chart[6] = time[0]/10 + '0';
	chart[7] = time[0]%10 + '0';

	g_mut_usb_print = CoCreateMutex();
	if( E_CREATE_FAIL == g_mut_usb_print )	{/*error handling*/} 

	Timer0Config();
	AdcConfig();
	PwmConfig();

	/* Configure Peripheral */
	uart_printf ("\r Initial hardware in Board :     \n\r");

	uart_printf ("\r RTC initial...                      ");
	RTC_Configuration  ();
	uart_printf (" [OK]. \n");

	uart_printf ("\r GPIO initial...                     ");
	GPIO_Configuration ();
	uart_printf (" [OK]. \n");

	uart_printf ("\r External interrupt initial...       ");
	EXIT_Configuration ();
	uart_printf (" [OK]. \n");

	LOCKREG();

	/* Create Tasks */
	CoCreateTask(
		task_temperature, (void*)0, TEMP_PRI, 
		&task_temp_stk[TASK_STK_SIZE-1], TASK_STK_SIZE);

	CoCreateTask(
		task_usb_listen, (void*)0, USB_LISTEN_PRI, 
		&task_usb_listen_Stk[TASK_STK_SIZE-1], TASK_STK_SIZE);

	CoExitTask();	 /*!< Delete 'task_init' task. 	*/
}

void C_Callback(uint32_t u32GpcStatus, uint32_t u32GpdStatus, uint32_t u32GpeStatus)
{
	CoEnterISR();                 /* Tell CooCox that we are starting an ISR. */
	if(u32GpcStatus==0x01)
		isr_SetFlag(button_sel_flg);
	else if (u32GpcStatus==0x02)
		isr_SetFlag(button_add_flg);

	CoExitISR();
}

void DrvRTC_TickISR(void)
{
//	CoEnterISR();                 /* Tell CooCox that we are starting an ISR. */
//	time[0]++;
//	if (time[0] == 60)
//	{
//		time[0] = 0;
//		time[1]++;
//		if (time[1] == 60)
//		{
//			time[1] = 0;
//			time[2]++;
//			if (time[2] == 24)
//				time[2] = 0;
//		}
//	}
//
//	isr_PostMail (mbox0,time);
//	CoExitISR();


}


/**
 *******************************************************************************
 *    Main function
 *******************************************************************************
 */
int main()
{
	UNLOCKREG();
  	SYS_Config();				/*!< Configure the system clocks      */
//	UART_Config ();				/*!< UART configuration               */
	LOCKREG();

	uart_printf ("\n\r\n\r");
	uart_printf ("\r System initial...                  ");
	uart_printf (" [OK]. \n");
	uart_printf ("\r System Clock have been configured as 60MHz!\n\n");

    uart_printf ("\r +------------------------------------------------+ \n");
	uart_printf ("\r | CooCox RTOS Demo for Cortex-M3 MCU(STM32F10x). |	\n");
	uart_printf ("\r | Demo in Keil MCBSTM32 Board.                   | \n");
	uart_printf ("\r +------------------------------------------------+ \n\n");



	uart_printf ("\r Initial CooCox RTOS...              ");
	CoInitOS();							/*!< Initial CooCox RTOS 			  */
	uart_printf (" [OK]. \n");


	uart_printf ("\r Create a \"task_init\" task...        ");
	CoCreateTask(task_init, (void *)0, 10, &task_init_Stk[TASK_STK_SIZE-1], TASK_STK_SIZE);
	uart_printf (" [OK]. \n");

	uart_printf ("\r Start multi-task.                   ");
	CoStartOS();

	while (1);
}
